<template>
  <a-modal
    title="年度预算详情"
    :visible="visible"
    :destroyOnClose="true"
    :maskClosable="false"
    @cancel="handleCancel"
    width="95%"
    :footer="null">
    <a-spin :spinning="spinning" tip="加载中...">
      <a-button type="primary" @click="onExcel">
        导出
      </a-button>
      <a-table
        :columns="columns"
        bordered
        :data-source="newSource"
        :scroll="{ x: 800, y: 500 }"
        :pagination="false"
        :rowKey="(record, index) => { return record.projectId }"
        :defaultExpandAllRows="true"
        v-if="newSource.length">
        <template slot="jan" slot-scope="text,record">
          <div class="editable-cell">
            <div class="editable-cell-text-wrapper">
              {{ text || ' ' }}
            </div>
          </div>
        </template>
        <!-- editable_feb -->
        <template slot="feb" slot-scope="text,record">
          <div class="editable-cell">
            <div class="editable-cell-text-wrapper">
              {{ text || ' ' }}
            </div>
          </div>
        </template>
        <!-- editable_apr -->
        <template slot="apr" slot-scope="text,record">
          <div class="editable-cell">
            <div class="editable-cell-text-wrapper">
              {{ text || ' ' }}
            </div>
          </div>
        </template>
        <!-- editable_may -->
        <template slot="may" slot-scope="text,record">
          <div class="editable-cell">
            <div class="editable-cell-text-wrapper">
              {{ text || ' ' }}
            </div>
          </div>
        </template>
        <!-- editable_jun -->
        <template slot="jun" slot-scope="text,record">
          <div class="editable-cell">
            <div class="editable-cell-text-wrapper">
              {{ text || ' ' }}
            </div>
          </div>
        </template>
        <!-- editable_jul -->
        <template slot="jul" slot-scope="text,record">
          <div class="editable-cell">
            <div class="editable-cell-text-wrapper">
              {{ text || ' ' }}
            </div>
          </div>
        </template>
        <!-- editable_aug -->
        <template slot="aug" slot-scope="text,record">
          <div class="editable-cell">
            <div class="editable-cell-text-wrapper">
              {{ text || ' ' }}
            </div>
          </div>
        </template>
        <!-- editable_sept -->
        <template slot="sept" slot-scope="text,record">
          <div class="editable-cell">
            <div class="editable-cell-text-wrapper">
              {{ text || ' ' }}
            </div>
          </div>
        </template>
        <!-- editable_oct -->
        <template slot="oct" slot-scope="text,record">
          <div class="editable-cell">
            <div class="editable-cell-text-wrapper">
              {{ text || ' ' }}
            </div>
          </div>
        </template>
        <!-- editable_nov -->
        <template slot="nov" slot-scope="text,record">
          <div class="editable-cell">
            <div class="editable-cell-text-wrapper">
              {{ text || ' ' }}
            </div>
          </div>
        </template>
        <!-- editable_dec -->
        <template slot="dec" slot-scope="text,record">
          <div class="editable-cell">
            <div class="editable-cell-text-wrapper">
              {{ text || ' ' }}
            </div>
          </div>
        </template>
        <!-- editable_mar -->
        <template slot="mar" slot-scope="text,record">
          <div class="editable-cell">
            <div class="editable-cell-text-wrapper">
              {{ text || ' ' }}
            </div>
          </div>
        </template>
      </a-table>
    </a-spin>
  </a-modal>
</template>

<script>
import { getBudgetsLaunch, addYearBudgets, detailBudgets, editYearBudgets, getExportExcel } from '@/api/budget'
import { cloneDeep } from 'lodash-es'
export default {
    data () {
        return {
            visible: false,
            dataSource: [],
            newSource: [], // 变化的源数据
            spinning: true,
            columns: [], // 头部表单

            editableData: {}, // 修改的位置数据
            previousData: {}, // 上一次的值
            editable: false, // 是否编辑

            // 接口参数
            addForm: {
                storeId: '',
                budgetType: '',
                budgetDate: '',
                title: '',
                description: '',
                janProjects: [],
                febProjects: [],
                marProjects: [],
                aprProjects: [],
                mayProjects: [],
                junProjects: [],
                julProjects: [],
                augProjects: [],
                septProjects: [],
                octProjects: [],
                novProjects: [],
                decProjects: []
            },
            visibleBtn: false,
            loadingBtn: false,
            projects: [],
            mode: 'add',
            titleMap: {
                add: '填报年度预算',
                edit: '修改年度预算'
            },
            rowData: '',

            // jan ,feb,apr, may,jun,jul,aug,sept,oct,nov,dec,mar
            editable_jan: false,
            editable_feb: false,
            editable_apr: false,
            editable_may: false,
            editable_jun: false,
            editable_jul: false,
            editable_aug: false,
            editable_sept: false,
            editable_oct: false,
            editable_nov: false,
            editable_dec: false,
            editable_mar: false,

            monthlyArr: ['jan', 'feb', 'apr', 'may', 'jun', 'jul', 'aug', 'sept', 'oct', 'nov', 'dec', 'mar']
        }
    },
    methods: {
        onExcel () {
            getExportExcel(this.rowData.budgetId).then(res => {
                const dataExcel = new Blob([res], {
                    type: 'application/vnd.ms-excel'
                })
                const downloadUrl = window.URL.createObjectURL(dataExcel)
                const anchor = document.createElement('a')
                anchor.href = downloadUrl
                anchor.download = '年度预算.xls' // 表格名称.文件类型
                anchor.click()
                window.URL.revokeObjectURL(res) // 消除请求接口返回的list数据
            })
        },
        // 全年累计
        getTotal (row) {
            let sum = 0
            const map = new Map(Object.entries(row))
            for (const [key, value] of map) {
                const index = this.monthlyArr.indexOf(key)
                if (index !== -1) {
                    sum += Number(value)
                }
            }
            return sum
        },
        edit (row, month) {
            this.editMonth(month)
            this.editableData[row.projectId] = cloneDeep(row)
            // 删除其他点击编辑的对象
            const obj = this.editableData
            for (const item in obj) {
                if (item != row.projectId) {
                    delete this.editableData[item]
                }
            }
        },
        save (row, month) {
            // this.editable = false

            this.calculate(row, month)
        },
        // 计算
        calculate (row, month) {
            this.fun1(row, month)
            const _this = this
            delete _this.editableData[row.projectId]
            this.cancelMonth(month)
        },
        fun1 (row, month) {
            // 替换当前编辑的值
            if (row.inOrOut == 2) {
                if (Number(row[month]) > 0) {
                    this.getObj(this.newSource, row.projectId, Number('-' + row[month]), row, month, callback)
                } else {
                    this.getObj(this.newSource, row.projectId, Number(row[month]), row, month, callback)
                }
            } else {
                this.getObj(this.newSource, row.projectId, Number(row[month]), row, month, callback)
            }
            // 计算处理时需要同步执行
            function callback (isFind, _this, row, month) {
                if (isFind) {
                    _this.fun2(row, month)
                }
            }
        },
        fun2 (row, month) {
            // 获取兄弟节点的父级id
            const brotherParentId = row.parentProjectId
            const MonthType = month
            // 获取兄弟节点数据
            const brotherParentArr = this.getBrotherParentId(this.newSource, brotherParentId, MonthType)
            if (brotherParentArr.length > 0) {
                // 兄弟数组的和  相差值
                const ParentVal = brotherParentArr.reduce((accumulator, currentValue) => Number(accumulator) + Number(currentValue))
                if (ParentVal) {
                    this.fun3(row, ParentVal, month)
                }
            }
        },
        fun3 (row, ParentVal, month) {
            // 相关连的数据包括原来未改变的初始值
            const joinedArr = this.get_level_all(this.dataSource, row.projectId).filter(item => item.projectId != row.projectId)

            const _this = this
            // 相差值
            if (joinedArr.length > 0) {
                joinedArr.forEach((item) => {
                    _this.getParentId(_this.newSource, item.projectId, Number(ParentVal), month)
                })
            }
        },
        // 根据id ，找到当前元素的对象，并进行赋值
        getObj (data, id, val, row, month, callback) {
            let isFind = false
            data.find((item) => {
                if (item.projectId === id) {
                    if (val == 0) item[month] = '0'
                    else item[month] = Number(val)
                    item.total = this.getTotal(item)
                    // item.promote = this.rateCompute(Number(item.preActual), Number(item.budget))
                    isFind = true
                } else if (item.children != null && item.children.length > 0) {
                    this.getObj(item.children, id, val, row, month, callback)
                }
            })
            if (isFind) {
                callback(isFind, this, row, month)
                return isFind
            }
        },
        // 根据id，找到所有的上级id
        get_level_all (data, id, arr = []) {
            data.find((item) => {
                if (item.projectId === id) {
                    arr.push(item)
                    return true
                } else if (item.children != null && item.children.length > 0) {
                    arr = this.get_level_all(item.children, id, arr)
                    if (arr.length) {
                        arr.push(item)
                        return true
                    } else {
                        return false
                    }
                }
                return false
            })
            return arr
        },
        // 根据id，找到所有的同级数据
        getBrotherParentId (data, id, month, arr = []) {
            data.find((item) => {
                if (item.parentProjectId == id) {
                    // 收支类型，1：收入，2：支出，3：其它
                    // 支出:减
                    if (item.inOrOut == '2') {
                        if (Number(item[month]) > 0) {
                            arr.push((item.inOrOut == '2' ? Number(('-' + item[month])) : Number(item[month])))
                        } else {
                            arr.push(Number(item[month]))
                        }
                    } else {
                        arr.push(Number(item[month]))
                    }
                } else if (item.children != null && item.children.length > 0) {
                    this.getBrotherParentId(item.children, id, month, arr)
                }
            })
            return arr
        },
        // 根据相差值遍历相关的父级或祖级
        getParentId (arr, id, numDiffer, month) {
            arr.forEach(item => {
                if (item.projectId == id) {
                    item[month] = Number(this.sumChildren(item.children, month))
                    item.total = this.getTotal(item)
                    // item.promote = this.rateCompute(item.preActual, item.budget)
                }
                if (item.children != null && item.children.length > 0) {
                    this.getParentId(item.children, id, numDiffer, month)
                }
            })
        },
        // 获取子集得计算和
        sumChildren (children, month) {
            let sum = 0
            children.map(item => {
                if (item.inOrOut == '2' && Number(item[month]) < 0) {
                    sum += Number(item[month])
                } else {
                    sum += item.inOrOut == '2' ? Number(('-' + item[month])) : Number(item[month])
                }
                // sum += item.inOrOut == '2' ? Number(item.budget) : Number(item.budget)
            })
            return sum
        },
        // 取消
        cancel (key, month) {
            // this.editable = false
            this.cancelMonth(month)
            delete this.editableData[key]
        },
        // 显示
        open (par) {
            this.dataSource = []
            this.columns = []
            this.visible = true
            // this.addForm = par
            this.addForm = {
                ...par,
                janProjects: [],
                febProjects: [],
                marProjects: [],
                aprProjects: [],
                mayProjects: [],
                junProjects: [],
                julProjects: [],
                augProjects: [],
                septProjects: [],
                octProjects: [],
                novProjects: [],
                decProjects: []
            }
            this.rowData = par
            detailBudgets(par.budgetId).then(res => {
                if (res.code == 200) {
                    const sheet = res.data.sheet
                    this.addForm.title = sheet.title
                    const headers = sheet.headers
                    headers.map(item => {
                        if (item.hidden == false) this.operator(item)
                    })
                    this.columns.push({
                        title: '全年累计',
                        dataIndex: 'total',
                        key: 'total',
                        align: 'left',
                        fixed: 'right',
                        width: 120,
                        scopedSlots: { customRender: 'total' }
                    })
                    const row = sheet.rows

                    this.handNull(row)
                    this.newSource = row
                    this.dataSource = row
                    this.spinning = false
                }
            })
        },
        // 子集没数据，赋值为空 null
        handNull (data) {
            data.forEach((item) => {
                // item.promote = this.rateCompute(item.preActual, item.budget)
                item.total = this.getTotal(item)
                if (item.children.length == 0) {
                    item.children = null
                } else {
                    this.handNull(item.children)
                }
            })
        },
        // columns 表头赋值
        operator (item) {
            const obj = {}
            if (item.columnId == 'projectName') {
                obj['title'] = item.name
                obj.dataIndex = 'name'
                obj.key = 'name'
                obj.align = 'left'
                obj.fixed = 'left'
                obj.width = 300
            } else {
                obj['title'] = item.name
                obj.dataIndex = item.columnId
                obj.key = item.columnId
                obj.align = 'left'
                obj.scopedSlots = { customRender: item.columnId }
                obj.width = 150
            }
            this.columns.push(obj)
        },
        // 关闭
        handleCancel () {
            this.visible = false
            this.editable = false
            this.$emit('close')
        },
        // 遍历表格并处理
        getArr (arr) {
            const _this = this
            arr.map(item => {
                if (item.projectId) {
                    const map = new Map(Object.entries(item))
                    for (const [key, value] of map) {
                        const index = this.monthlyArr.indexOf(key)
                        if (index !== -1) {
                            _this.addForm[key + 'Projects'].push({ projectId: item.projectId, budgetAmount: value })
                        }
                    }
                }

                // this.projects.push({ projectId: item.projectId, budgetAmount: item.budget })
                if (item.children != null && item.children.length > 0) {
                    this.getArr(item.children)
                }
            })
        },
        // 修改月份的一列
        editMonth (monthType) {
            // jan ,feb,apr, may,jun,jul,aug,sept,oct,nov,dec,mar
            this.monthlyArr.map(item => {
                // 除了修改的这个月份，其他都关闭
                if (item == monthType) {
                    this['editable_' + item] = true
                } else {
                    this['editable_' + item] = false
                }
            })
        },
        // 取消月份的一列
        cancelMonth (monthType) {
            this.monthlyArr.map(item => {
                this['editable_' + item] = false
            })
        }
    }
}
</script>
<style scoped></style>
